package com.subang.common.utils;

import cn.hutool.http.*;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.springframework.beans.factory.annotation.Value;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

public class WeChatUtil {

    //微信小程序appId
    @Value("${wechat.appId}")
    private String appid;

    //微信小程序密钥
    @Value("${wechat.appSecret}")
    private String secret;


    // 微信API的URL，用于文本安全检测
    private static final String MSG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=ACCESS_TOKEN";

    // 微信API的URL，用于获取access_token
    private static final String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=SECRET";

    // 微信API的URL，这里是一个示例，实际URL可能会根据微信API文档有所不同
    private static final String USER_INFO_URL = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

    // 存储access_token及其过期时间
    private static String accessToken;
    private static long expirationTime;

    /**
     * 根据appid和secret获取access_token
     *
     * @param appid 应用的appid
     * @param secret 应用的secret
     * @return 包含access_token的JSONObject，如果出错则返回null
     */
    public static JSONObject getAccessToken(String appid, String secret) {
        try {
            // 先检查是否已经存在有效的access_token
            if (accessToken!= null && System.currentTimeMillis() < expirationTime) {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("access_token", accessToken);
                return jsonObject;
            }

            // 构造完整的URL
            String fullUrl = TOKEN_URL.replace("APPID", appid).replace("SECRET", secret);

            // 发起HTTP GET请求
            URL url = new URL(fullUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Content - Type", "application/json; utf - 8");

            // 获取响应
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String inputLine;
                StringBuilder content = new StringBuilder();
                while ((inputLine = in.readLine())!= null) {
                    content.append(inputLine);
                }
                in.close();
                JSONObject jsonObject = new JSONObject(content.toString());
                accessToken = jsonObject.getStr("access_token");
                // 假设响应中有expires_in字段表示有效期（秒数）
                int expiresIn = jsonObject.getInt("expires_in");
                expirationTime = System.currentTimeMillis()+(expiresIn * 1000);
                return jsonObject;
            } else {
                // 处理错误响应
                // 这里只是简单地返回null，你可能需要记录错误或抛出异常
                return null;
            }
        } catch (Exception e) {
            // 处理异常，例如记录日志或抛出运行时异常
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 请求微信接口服务，用code换取用户手机号（每个code只能使用一次，code的有效期为5min）
     * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/phonenumber/phonenumber.getPhoneNumber.html
     *
     * @param code
     * @param accessToken
     * @return
     */
    public static JSONObject getPhoneNumber(String code, String accessToken) {
        String result = null;
        try {
            // 接口调用凭证：accessToken
            String baseUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken;
            HashMap<String, Object> requestParam = new HashMap<>();
            // 手机号调用凭证
            requestParam.put("code", code);
            // 发送post请求读取调用微信接口获取openid用户唯一标识
            String jsonStr = JSONUtil.toJsonStr(requestParam);
            HttpResponse response = HttpRequest.post(baseUrl)
                    .header(Header.CONTENT_ENCODING, "UTF-8")
                    // 发送json数据需要设置contentType
                    .header(Header.CONTENT_TYPE, "application/x-www-form-urlencoded")
                    .body(jsonStr)
                    .execute();
            if (response.getStatus() == HttpStatus.HTTP_OK) {
                result = response.body();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return JSONUtil.parseObj(result);
    }

    /**
     * 根据access_token和openid获取用户信息
     *
     * @param accessToken 有效的access_token
     * @param openId      用户的openid
     * @return 包含用户信息的JSONObject，如果出错则返回null
     */
    public static JSONObject getUserInfo(String accessToken, String openId) {
        try {
            // 构造完整的URL
            String fullUrl = USER_INFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);

            // 发起HTTP GET请求
            URL url = new URL(fullUrl);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("GET");

            // 获取响应
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String inputLine;
                StringBuilder content = new StringBuilder();
                while ((inputLine = in.readLine()) != null) {
                    content.append(inputLine);
                }
                in.close();

                // 将响应转换为JSONObject
                return new JSONObject(content.toString());
            } else {
                // 处理错误响应
                // 这里只是简单地返回null，你可能需要记录错误或抛出异常
                return null;
            }
        } catch (Exception e) {
            // 处理异常，例如记录日志或抛出运行时异常
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 检测文本内容是否含有违法违规内容
     *
     * @param accessToken 有效的access_token
     * @param content     要检测的文本内容
     * @return 检测结果的JSONObject，如果出错则返回null
     */
    public static JSONObject msgSecCheck(String accessToken, String content) {
        // 构造完整的URL
        String fullUrl = MSG_SEC_CHECK_URL.replace("ACCESS_TOKEN", accessToken);

        // 构造请求参数
        Map<String, Object> requestParam = new HashMap<>();
        requestParam.put("content", content);

        // 将请求参数转换为JSON字符串
        String jsonStr = JSONUtil.toJsonStr(requestParam);

        // 发起HTTP POST请求
        try {
            HttpResponse response = HttpRequest.post(fullUrl)
                    .header(Header.CONTENT_TYPE, "application/json")
                    .body(jsonStr)
                    .execute();

            // 检查响应状态码
            if (response.getStatus() == HttpStatus.HTTP_OK) {
                // 返回响应的JSON对象
                return JSONUtil.parseObj(response.body());
            } else {
                // 记录错误响应
                System.err.println("Error response status: " + response.getStatus());
                System.err.println("Error response body: " + response.body());
                return null;
            }
        } catch (Exception e) {
            // 记录异常信息
            e.printStackTrace();
            return null;
        }
    }
}